<template>
    <div class="frame-container">
        <div id="container">

        </div>
        <div id="gui-container"></div>
    </div>
</template>

<script setup lang="ts">
import * as THREE from 'three';
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js';
import { onMounted } from 'vue';
import AxisGridHelper from '../utils/AxisGridHelper';
import { GUI } from 'three/addons/libs/lil-gui.module.min.js';

const objects:THREE.Object3D[] = [];
function init(scene:THREE.Scene, camera:THREE.PerspectiveCamera, renderer:THREE.WebGLRenderer){
    const radius = 1;
    const widthSegments = 6;
    const heightSegments = 6;

    //添加一个太阳系子系统
    const solarSystem = new THREE.Object3D();
    scene.add(solarSystem);
    objects.push(solarSystem);
    //太阳
    const sphereGeometry = new THREE.SphereGeometry(radius, widthSegments, heightSegments);
    const sohereMaterial = new THREE.MeshPhongMaterial({ emissive: 0xffff00 }); //使用反射材质，这种材质在没有环境光或者其他光源的情况下也是可见的
    const sunMesh = new THREE.Mesh(sphereGeometry, sohereMaterial);
    sunMesh.scale.set(5,5,5);
    // scene.add(sunMesh);
    solarSystem.add(sunMesh);
    objects.push(sunMesh);


    //添加一个地月子系统
    const earthOrbit = new THREE.Object3D();
    earthOrbit.position.x = 10;
    solarSystem.add(earthOrbit);
    objects.push(earthOrbit);
    //地球
    const earthMaterial = new THREE.MeshPhongMaterial({   
        color: 0x2233ff,
        emissive: 0x112244
     });
     const earthMesh = new THREE.Mesh(sphereGeometry, earthMaterial);
    //  earthMesh.position.set(10, 0, 0);
    //  scene.add(earthMesh);
    // solarSystem.add(earthMesh);
    earthOrbit.add(earthMesh);
    objects.push(earthMesh);

    //添加一个月球子系统
    const moonOrbit = new THREE.Object3D();
    moonOrbit.position.x = 2;
    earthOrbit.add(moonOrbit);

    const moonMaterial = new THREE.MeshPhongMaterial({
        color: 0x888888,
        emissive: 0x222222
    });
    const moonMesh = new THREE.Mesh(sphereGeometry, moonMaterial);
    moonMesh.scale.set(0.5, 0.5, 0.5);
    moonOrbit.add(moonMesh);
    objects.push(moonMesh);

    const container = document.getElementById("gui-container");
    const gui = new GUI({container:container!!});

    makeAxisGrid( solarSystem, 'solarSystem',gui, 26 );
	makeAxisGrid( sunMesh, 'sunMesh',gui );
	makeAxisGrid( earthOrbit, 'earthOrbit',gui );
	makeAxisGrid( earthMesh, 'earthMesh',gui );
	makeAxisGrid( moonOrbit, 'moonOrbit',gui );
	makeAxisGrid( moonMesh, 'moonMesh',gui );

}

function makeAxisGrid(node:THREE.Object3D,label:string,gui:GUI,units:number=10){
    const helper = new AxisGridHelper(node,units);
    gui.add(helper,'visible').name(label);

}


onMounted(() => {
    const scene = new THREE.Scene();
    const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
    camera.position.set(0, 50,0);
    camera.up.set(0,0,1);
    camera.lookAt(0,0,0);
    const renderer = new THREE.WebGLRenderer({antialias: true}); //开启抗锯齿
    renderer.setClearColor(0x000000);
    renderer.setSize(window.innerWidth, window.innerHeight);
    document.getElementById("container")?.appendChild(renderer.domElement);
    // document.body.appendChild(renderer.domElement);

    const control = new OrbitControls(camera, renderer.domElement);
    control.enableDamping = true;

    //添加一个点光源
    const color = 0xffffff;
    const intensity = 30;
    const light = new THREE.PointLight(color, intensity);
    scene.add(light);

    init(scene,camera,renderer);

    //为所有物体添加坐标轴
    // objects.forEach((node) => {
    //     const axes = new THREE.AxesHelper();
    //     axes.material.depthTest = false;
    //     axes.renderOrder = 1;
    //     node.add(axes);
    // });

    const clock = new THREE.Clock();

    const animationFuc = () => { 
        const delta = clock.getDelta(); //这里必须接收该值，连续调用它会导致获取的值接近于0
        objects.forEach((obj) => {
            obj.rotation.y += delta;
        });
        renderer.render(scene, camera);
        control.update();
        requestAnimationFrame(animationFuc);
    }
    animationFuc();

    window.addEventListener('resize', () => { 
        renderer.setSize(window.innerWidth, window.innerHeight);
    });
})


</script>

<style scoped>
.frame-container {
    position: relative; /*建立定位上下文，使得子元素的定位以父布局的位置为基准，而不是以整个文档为基准*/
  }
  
  .frame-container > * {
    position: absolute; /*子布局使用绝对位置，绝对定位会自动向上寻找到有定位设置的父元素，如果没有就会找到最终的视口，最后变成相对视口的绝对定位，所以一般要和父布局的相对定位配合使用*/
    top: 0;
    left: 0;
  }
</style>